from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings

# Create your tests here.
from rest_framework import status
from rest_framework.response import Response
from rest_framework_jwt.settings import api_settings
from rest_framework.views import APIView

from carts.utils import merge_cart_cookie_to_redis
from .serializers import QQAuthUserSerializer


from .models import OAuthQQUser

import logging

from .utils import generate_save_user_token

logger = logging.getLogger('django')


class QQauthURLView(APIView):
    """拼接QQ登录网址"""

    def get(self, request):
        # 提取前端传入的next参数记录用户从哪里到的login界面
        next = request.query_params.get('next') or '/'
        # 2.利用QQ登录SDK
        # 创建QQ工具对象
        # 调用它里面的方法 拼接好QQ登录网址
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI, state=next)
        login_url = oauth.get_qq_url()
        print(login_url)

        return Response({'login_url': login_url, 'next': next})


class QQAuthUserView(APIView):

    def get(self, request):
        """QQ登录成功后的回调处理"""
        # 获取前端传入的code
        code = request.query_params.get('code')
        print(code)
        if not code:
            return Response(status=status.HTTP_400_BAD_REQUEST, data={"message": "缺少code"})
        # 创建QQ登录工具对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)
        try:
            # 调用它里面get_access_token(code) 用code向QQ服务器获取access_token
            access_token = oauth.get_access_token(code)
            print(access_token)
            # 调用它里面的get_open_id(access_token) 用access_token响应QQ服务器openid
            openid = oauth.get_open_id(access_token)
            print(openid)
        except Exception as e:
            print(e)
            logging.error(e)
            return Response({"message": "QQ服务器不可用"}, status=status.HTTP_503_SERVICE_UNAVAILABLE)
        # 查询数据库有没有这个openid
        try:
            authQQUserModel = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 如果没有这个openid 应该创建一个新用户和此openid绑定，把openid加密之后响应给前端，让前端先存一会 等待绑定时使用
            # 因为我们无法在此方法里创建一个新用户与此openid绑定 需将openid返回给前端，让前端携带此openid发请求创建用户(如果未存在)来绑定
            access_token = generate_save_user_token(openid)
            return Response({
                "access_token": access_token
            })
        else:
            # 如果数据库中有此openid 直接登录成功 返回jwt 状态保存信息
            user = authQQUserModel.user

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)

            response = Response({
                "token": token,
                "username": user.username,
                "user_id": user.pk
            })
            merge_cart_cookie_to_redis(request, user, response)
            return response

    def post(self, request):
        """openid绑定用户接口"""
        # 创建序列化器进行反序列化
        serializer = QQAuthUserSerializer(data=request.data)
        # 调用is_valid方法进行校验
        serializer.is_valid(raise_exception=True)
        # 调用序列化器的save方法
        user = serializer.save()
        # 生成jwt 状态保存 token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        # 响应
        response = Response({
            "token": token,
            "username": user.username,
            "user_id": user.pk
        })
        merge_cart_cookie_to_redis(request, user, response)
        return response
